home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 6 / FM Towns Free Software Collection 6.iso / t_os / tiffsmt / tiffsmt.c next >
Text File  |  1993-07-08  |  11KB  |  326 lines

  1. /*
  2. **【 作品名 】 TIFFSMT
  3. **【 版  数 】 V1.0  L10
  4. **【 作  者 】 WAVE  Soft 
  5. **【 日  付 】 1993.2.7
  6. **             1993.2.21 修正
  7. **
  8. **【 説  明 】 ソフトウェア種別:画像処理ソフト(フィルター)
  9. **             ビデオカードからデジタイズした画像の画像処理を行います。
  10. **             処理は、各ドットの回りにあるドットを調べて、平滑化しています。
  11. **              
  12. **             使い方はコンソールから
  13. **          
  14. **                run386 tiffsmt.exp -l level -o outfile.tif infile
  15. **                 level:   1 から 93 までの数字を指定する
  16. **                 outfile: 処理した画像を保存するファイル名
  17. **                 infile:  デジタイズした画像のファイル  
  18. **
  19. **                                                   (C) 1993 WAVE Soft
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <DOS.h>        /* _FP_SEG(), _FP_OFF()   */
  26. #include <egb.h>
  27.  
  28. #define  PROTO
  29. #define  CLEAR_CODE  256
  30. #define  EOF_CODE    257
  31. #define  MAXTABLE    4096
  32.  
  33. char gwork[EgbWorkSize];
  34.  
  35. typedef struct {
  36.    char  *fname;  /*  画像の名前   */
  37.    short xsize ;  /*  横のドット数 */
  38.    short ysize ;  /*  縦のドット数 */
  39.    short bpixel;  /*  ピクセルのドット数 1:2 4:16 8:256 16:32768 色を示す。 */
  40.    char  comprs;  /*  圧縮の状態       1:無 5:LZW */
  41.    char  phintp;  /*  0:モノクロ  1:カラー  3:パレット */
  42.    short imgoff;  /*  画像データへのoffset */  
  43.    short pltoff;  /*  パレットデータへのoffset  0:パレット未使用 */
  44.    long  ibyte ;  /*  画像データのバイト数 */
  45.    } tiff_tag;
  46. tiff_tag t;
  47.  
  48. unsigned short awork[240][320]; /* 画像データ */
  49. unsigned char  fwork[0x200];    /* TAG データ */
  50.  
  51. int main(int argc, char *argv[])
  52. {
  53.   const char *inpfile="";
  54.   const char *outfile="tiffsmt.tif";
  55.   int  level=16,count=1;
  56.   char para[64];
  57.   int  ret,i;
  58.  
  59.   if(argc==1) 
  60.    {printf("option: [-l level] [-c count] [-o outfile] infilename\n");
  61.     puts("         level      = 0 ` 93(defaut:16)");
  62.     puts("         outfile    = save するファイル名(default:tiffsmt.tif)");
  63.     puts("         infilename = 処理するファイル名 '.tif' にしてね");
  64.     puts("                      320*240 の 32K色の画像が対象です。");
  65.     return 1;
  66.    } 
  67.  
  68.   for(i=1; i<argc; i++)
  69.     {
  70.          if(strcmp(argv[i],"-l")==0) {i++;level=atoi(argv[i]);}
  71.     else if(strcmp(argv[i],"-c")==0) {i++;count=atoi(argv[i]);}
  72.     else if(strcmp(argv[i],"-o")==0) {i++;outfile=argv[i];}
  73.     else inpfile=argv[i];
  74.     }
  75.  
  76.   if( (ret=load_tiff(inpfile,awork))== -1 ) 
  77.      {printf("%s がロードできんかった。\n",inpfile);return ret;}
  78.   if( ret== -2 ) 
  79.      {printf("このTIFF 形式 のヘッダは扱えないよ。\n");return ret;}
  80.   if( ret== -3 ) 
  81.      {printf("このTIFF 形式 ファイルは扱えないよ。\n");
  82.       printf("ファイル名: %s のデータ\n",t.fname);
  83.       printf("横のドット数 = %d\n",t.xsize);
  84.       printf("縦のドット数 = %d\n",t.ysize);
  85.       printf("ピクセルのドット数(1:2 4:16 8:256 16:32768) = %d\n",t.bpixel);
  86.       printf("圧縮の状態(1:無 5:LZW ) = %d\n",t.comprs);
  87.       printf("画像の種類(0:モノクロ  1:カラー  3:パレット) = %d\n",t.phintp);
  88.       return ret;}
  89.  
  90.   set_screen();
  91.   DWORD(para  )=(unsigned int)awork;
  92.   WORD(para+ 4)=0x14;
  93.   WORD(para+ 6)=0;
  94.   WORD(para+ 8)=0;
  95.   WORD(para+10)=t.xsize-1;
  96.   WORD(para+12)=t.ysize-1;
  97.   EGB_putBlock(gwork,0,para);
  98.  
  99.   for(i=0;i<count;i++)
  100.   { char para[64];
  101.     DWORD(para  )=(unsigned int)awork;
  102.     WORD(para+ 4)=0x14;
  103.     WORD(para+ 6)=0;
  104.     WORD(para+ 8)=0;
  105.     WORD(para+10)=t.xsize-1;
  106.     WORD(para+12)=t.ysize-1;
  107.     EGB_getBlock(gwork,para);
  108.     flat(level);
  109.   }
  110.   { char para[64];
  111.     DWORD(para  )=(unsigned int)awork;
  112.     WORD(para+ 4)=0x14;
  113.     WORD(para+ 6)=0;
  114.     WORD(para+ 8)=0;
  115.     WORD(para+10)=t.xsize-1;
  116.     WORD(para+12)=t.ysize-1;
  117.     EGB_getBlock(gwork,para);
  118.   }
  119.  
  120.   if( (ret=save_tiff(outfile,awork))!=0 ) 
  121.      {printf("ファイル %s への書き込みができませんでした。\n",outfile);
  122.       return ret;}
  123.  
  124.   return 0;
  125. }
  126.  
  127. int flat(int level)
  128. {
  129.   _far unsigned short *vram1;
  130.   int  i,j;
  131.  
  132. #define COLSP(x,g,r,b) { b=x & 0x001f; r=(x & 0x03e0)>>5; g=x>>10;}
  133. #define COLCN(x,g,r,b) { x = b | (r<<5) | (g<<10); }
  134. #define COLDF(g1,r1,b1,g2,r2,b2) ( _abs((g2)-(g1))+_abs((r2)-(r1))+_abs((b2)-(b1)))
  135.  
  136.   _FP_SEG( vram1 ) = 0x104;     /* 又は 0x10c  */
  137.   _FP_OFF( vram1 ) = 256*1024;
  138.  
  139.   for( j=1; j<239; j++)
  140.     for(i=1; i<319; i++)
  141.     {
  142.     int k,n,av,ag,ar,ab, g[9],r[9],b[9];
  143.  
  144.     av=awork[j][i]; COLSP( av, ag, ar, ab);
  145.     av=awork[j-1][i-1]; COLSP( av, g[0], r[0], b[0]);  
  146.     av=awork[j-1][i  ]; COLSP( av, g[1], r[1], b[1]);  
  147.     av=awork[j-1][i+1]; COLSP( av, g[2], r[2], b[2]);  
  148.     av=awork[j  ][i-1]; COLSP( av, g[3], r[3], b[3]);  
  149.     av=awork[j  ][i  ]; COLSP( av, g[8], r[8], b[8]);  
  150.     av=awork[j  ][i+1]; COLSP( av, g[4], r[4], b[4]);  
  151.     av=awork[j+1][i-1]; COLSP( av, g[5], r[5], b[5]);  
  152.     av=awork[j+1][i  ]; COLSP( av, g[6], r[6], b[6]);  
  153.     av=awork[j+1][i+1]; COLSP( av, g[7], r[7], b[7]);  
  154.     for(n=1,k=0;k<8;k++)
  155.       {
  156.       if( COLDF( g[8],r[8],b[8],g[k],r[k],b[k] ) <= level ) 
  157.          {ag+=g[k];ar+=r[k];ab+=b[k];n++;}
  158.       }
  159.     ag/=n;ar/=n;ab/=n;
  160.     COLCN( av, ag, ar, ab);
  161.     /* awork[j][i]=vram1[j*512+i]=av ; */
  162.     vram1[j*512+i]=av ; 
  163.     }
  164.  
  165.   return 0;
  166. }
  167.  
  168. int  set_screen()
  169. {
  170.  
  171.   EGB_init(gwork,EgbWorkSize);   /* 画面初期化 */
  172.   EGB_resolution(gwork,0,3);     /* page=0;mode */
  173.   EGB_writePage(gwork,0);
  174.   EGB_displayStart(gwork,0,0,0); /* 表示開始位置 (0,0) */
  175.   EGB_displayStart(gwork,1,0,0); /* 仮想画面の表示位置 */
  176.   EGB_displayStart(gwork,2,1,1); /* 拡大 */
  177.   EGB_displayStart(gwork,3,640,480); /* 画面のサイズ */
  178.   EGB_resolution(gwork,1,10);     /* page=1;mode */
  179.   EGB_writePage(gwork,1);
  180.   EGB_displayStart(gwork,0,0,0); /* 表示開始位置 (0,0) */
  181.   EGB_displayStart(gwork,1,0,0); /* 仮想画面の表示位置 */
  182.   EGB_displayStart(gwork,2,2,2); /* 拡大 */
  183.   EGB_displayStart(gwork,3,320,240); /* 画面のサイズ */
  184.   EGB_displayPage(gwork,0,3);        /* page0 前 page1,2表示 */
  185.  
  186.   return 0;
  187. }
  188.  
  189. int load_tiff( const char *fname, char *awork)
  190. {
  191.   int ret;
  192.  
  193.   t.fname=(char *)fname;
  194.   if( (ret=tiff_getattr(&t) )!=0 ) return ret;
  195.   if( (ret=tiff_getimg( &t, (char *)awork))!=0 ) return ret;
  196.   if( t.bpixel!=16 ) return -3;
  197.   if( t.xsize >320 ) return -3;
  198.   if( t.ysize >240 ) return -3;
  199.   return 0;
  200. }
  201.  
  202. /**/
  203. PROTO int tiff_getattr( tiff_tag *t )
  204. /*
  205.  *  fname = ファイルネーム(拡張子も付ける)
  206.  *  xsize = 横のドット数
  207.  *  ysize = 縦のドット数
  208.  *  bpixel= ピクセルのドット数        1:2 4:16 8:256 16:32768 色を示す。
  209.  *  comprs= 圧縮の状態                1:無 5:LZW
  210.  *  phintp= 0:モノクロ  1:カラー  3:パレット 
  211.  *  imgoff= 画像データへのoffset  
  212.  *  pltoff= パレットデータへのoffset  0:パレット未使用
  213.  *  ibyte = 画像データのバイト数
  214.  */
  215. {
  216.   FILE *fp;
  217.   int i;
  218.  
  219.   if((fp=fopen(t->fname, "rb"))==NULL) return -1;
  220.   if(fread( fwork, 1,0x200,fp) != 0x200)   {fclose(fp); return -1;}
  221.   t->xsize= t->ysize= t->bpixel= t->comprs= t->imgoff= t->pltoff= t->ibyte=0;
  222.   if(fclose(fp)) return -1;
  223.   if( strncmp( (const char*)fwork,"\x49\x49\x2a\x00\x08\x00\x00\x00",8)!=0) 
  224.      return -2;
  225.     
  226.   for(i=0; i< WORD(fwork+8); i++)
  227.     switch(WORD(fwork+0xa+i*12))
  228.        {
  229.        case 0x0100: t->xsize =(short) DWORD(fwork+0x12+i*12); break;
  230.        case 0x0101: t->ysize =(short) DWORD(fwork+0x12+i*12); break;
  231.        case 0x0102: t->bpixel=(short) DWORD(fwork+0x12+i*12); break;
  232.        case 0x0103: t->comprs=(char)  DWORD(fwork+0x12+i*12); break;
  233.        case 0x0106: t->phintp=(char)  DWORD(fwork+0x12+i*12); break;
  234.        case 0x0111: t->imgoff=(short) DWORD(fwork+0x12+i*12); break;
  235.        case 0x0117: t->ibyte =(long)  DWORD(fwork+0x12+i*12); break;
  236.        case 0x0140: t->pltoff=(short) DWORD(fwork+0x12+i*12); break;
  237.        };
  238.   if( (t->bpixel != 16) || (t->phintp != 1) ) return -3;
  239.   if( (t->comprs !=  1) && (t->comprs != 5) ) return -3;
  240.   return 0;
  241. }
  242.  
  243. /**/
  244. PROTO int tiff_getimg( tiff_tag *t, char *ibuf)
  245. {
  246.   FILE *fp;
  247.   int datasz;
  248.   if((fp=fopen(t->fname, "rb"))==NULL) return -1;
  249.   if(fseek(fp,t->imgoff,SEEK_SET))   {fclose(fp); return -1;}
  250.   datasz=fread( ibuf, 1, 240*320*2,fp); 
  251.   if(fclose(fp)) return -1;
  252.   if( t->comprs == 5) 
  253.     {   char *mv;
  254.         t->comprs = 1;
  255.         mv=ibuf+(320*240*2-datasz);
  256.         _rmemcpy(mv,ibuf,datasz);
  257.         tiff_uncmp2( ibuf, (const char *)mv, datasz);
  258.     }
  259.   t->ibyte  = t->xsize * t->ysize*2; 
  260.   return 0; 
  261. }
  262.  
  263. /**/
  264. PROTO int save_tiff(const char *savefile, char *awork)
  265. {
  266.   FILE *fp;
  267.   int i;
  268.  
  269.   for(i=0; i< WORD(fwork+8); i++)
  270.     switch(WORD(fwork+0xa+i*12))
  271.        {
  272.        case 0x0103: DWORD(fwork+0x12+i*12)=1 ; break;
  273.        case 0x0117: DWORD(fwork+0x12+i*12)=t.xsize*t.ysize*2  ; break;
  274.        };
  275.   if((fp=fopen(savefile, "wb"))==NULL) return -1;
  276.   if(fwrite( fwork,1,    0x200,fp) !=    0x200 ) {fclose(fp);return -1;}
  277.   if(fwrite( awork,1, t.ibyte,fp) != t.ibyte ) {fclose(fp);return -1;}
  278.   if(fclose(fp)) return -1;
  279.   return 0;
  280. }
  281.  
  282. /**/
  283. /* LZW 圧縮されたデータを展開する             */
  284. /* 1992-2 OH! FM TOWNS p.75 を参考にした      */
  285. /* expand :展開する領域の先頭アドレス         */ 
  286. /* indata :圧縮されたデータ                   */
  287. /* 戻り値 :展開したバイト数 エラーのときは  0 */
  288. /* 使用メモリー : stack 33K bytes             */
  289. PROTO int tiff_uncmp2( char *expand, const char *indata, int insize)
  290. {
  291.   struct { char *s,*e; } table[MAXTABLE];
  292.   char chrd[256];
  293.   char *outdata;
  294.   int  cbl,btp,table_ix;
  295.   unsigned int code;
  296.   int  i;
  297.   btp=0; outdata= expand;
  298.   for(i=0;i<256;i++) {chrd[i]=i;table[i].s=table[i].e=&chrd[i];}
  299.   table_ix=EOF_CODE+1;
  300.   cbl=9;i=0;
  301.   while( i++ < insize )  { 
  302.       /*  ret = ((indata[0]*256+indata[1])*256+indata[2])*256 ; */
  303.       code = ((((indata[0]<<8) | indata[1])<<8) | indata[2])<<8 ; 
  304.       code = code << btp  ;
  305.       code = code >> (32-cbl) ;
  306.       btp=cbl-(8-btp); indata++;
  307.       while( btp >= 8 ) {indata++; btp-=8;}
  308.       if( code == EOF_CODE ) {
  309.       break;
  310.       } else if( code == CLEAR_CODE ) {              /* クリアコード */
  311.             table_ix=EOF_CODE+1;
  312.             cbl=9;
  313.       } else if( code < table_ix ) {                 /* テーブルに存在 */
  314.             register char *p;
  315.             table[table_ix].s=outdata;
  316.             for( p=table[code].s; p<=table[code].e; *outdata++=*p++);
  317.             table[table_ix++].e=outdata; 
  318.             if(table_ix==(1<<cbl)) {cbl++; if(cbl>=13) cbl=12;}
  319.       } else { 
  320.             return 0;
  321.       } 
  322.   }
  323.   return (int) (outdata-expand);
  324. }
  325.  
  326.